package top.korori.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.korori.entity.SysMenu;
import top.korori.entity.bo.SysMenuBo;
import top.korori.entity.vo.SysMenuVo;
import top.korori.enums.SysMenuStatus;
import top.korori.mapper.SysMenuMapper;
import top.korori.service.SysMenuService;
import top.korori.service.SysRoleMenuService;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 
 * 后台菜单表 服务实现类
 * 
 *
 * @author korori
 * @since
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Override
    public Set<String> getPermsByUserId(Long userId) {
        return baseMapper.getPermsByUserId(userId);
    }

    @Override
    public List<SysMenuVo> tree() {
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(SysMenu::getSort);
        List<SysMenu> sysMenusList = this.list(queryWrapper);
        List<SysMenuVo> sysMenuVos = BeanUtil.copyToList(sysMenusList, SysMenuVo.class);
        List<SysMenuVo> pSysMenuVos = sysMenuVos.stream().filter(sysMenuVo -> sysMenuVo.getPid().equals(0L)).collect(Collectors.toList());
        return splicing(sysMenuVos, pSysMenuVos);
    }

    @Override
    public void add(SysMenuBo sysMenuBo) {
        SysMenu sysMenu = BeanUtil.copyProperties(sysMenuBo, SysMenu.class);
        this.save(sysMenu);
    }

    @Override
    public void edit(SysMenuBo sysMenuBo) {
        SysMenu sysMenu = BeanUtil.copyProperties(sysMenuBo, SysMenu.class);
        this.updateById(sysMenu);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void del(List<Long> menuIds) {
        this.removeByIds(menuIds);
        sysRoleMenuService.delByMenuIds(menuIds);
    }

    @Override
    public List<SysMenuVo> treeByUserId(Long userId) {
        List<SysMenuVo> sysMenuVos;
        if (ObjectUtil.equal(userId,1L)){
            List<SysMenu> list = this.lambdaQuery().orderByAsc(SysMenu::getSort).list();
            sysMenuVos = BeanUtil.copyToList(list, SysMenuVo.class);
        }else {
            sysMenuVos = baseMapper.getByUserId(userId);
        }
        List<SysMenuVo> pSysMenuVos = sysMenuVos.stream().filter(sysMenuVo -> sysMenuVo.getPid().equals(0L)).collect(Collectors.toList());
        return splicing(sysMenuVos, pSysMenuVos);
    }

    @Override
    public List<Long> treeMenuByRoleId(Long roleId) {
        List<SysMenu> sysMenuVos = baseMapper.getMenuByRoleId(roleId);
        return sysMenuVos.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
    }

    @Override
    public List<SysMenuVo> selectTree() {
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getStatus, SysMenuStatus.NORMAL.getCode());
        queryWrapper.orderByAsc(SysMenu::getSort);
        List<SysMenu> sysMenus = baseMapper.selectList(queryWrapper);
        List<SysMenuVo> sysMenuVos = BeanUtil.copyToList(sysMenus, SysMenuVo.class);
        List<SysMenuVo> pSysMenuVos = sysMenuVos.stream().filter(sysMenuVo -> sysMenuVo.getPid().equals(0L)).collect(Collectors.toList());
        return splicing(sysMenuVos,pSysMenuVos);
    }

    private List<SysMenuVo> splicing(List<SysMenuVo> sysMenuVos, List<SysMenuVo> pSysMenuVos) {
        pSysMenuVos.forEach(pSysMenuVo -> {
            List<SysMenuVo> children = sysMenuVos.stream().filter(sysMenuVo -> pSysMenuVo.getMenuId().equals(sysMenuVo.getPid())).collect(Collectors.toList());
            this.splicing(sysMenuVos, children);
            pSysMenuVo.setChildren(children);
        });
        return pSysMenuVos;
    }
}
